<?php


namespace app\admin\logic;

use app\admin\library\Auth;
use think\Db;
use think\exception\PDOException;
use think\exception\ValidateException;

abstract class BaseLogic
{
    protected static $instance = [];
    protected $model;

    /**
     * 关联查询，需要在模型中定义关联模型
     * @var
     */
    protected $with;

    /**
     * 扩展检索条件
     * @var
     */
    protected $whereExtend;

    /**
     * 是否启用模型验证
     * @var bool
     */
    protected $modelValidate = false;

    /**
     * 场景验证
     * @var bool
     */
    protected $modelSceneValidate = false;

    public function __construct()
    {

    }

    /**
     * 初始化.
     *
     * @param array $options 参数
     *
     * @return \app\admin\logic\BaseLogic
     */
    public static function instance()
    {
        if (!(isset(static::$instance[static::class]) && is_null(static::$instance[static::class]))) {
            static::$instance[static::class] = new static();
        }

        return static::$instance[static::class];
    }


    /**
     * 用于显示列表
     * @param $param
     * @return array
     */
    public function getList($param)
    {
        $total = $this->countAll($param);
        $rows = $this->getAll($param);
        return compact('total', 'rows');
    }

    /**
     * 获取年份列表
     * @return mixed
     */
    public function getYearList()
    {
        for ($i = 1; $i <= 5; $i++) {
            $y = (int) date('Y') + $i;
            $yearList[$y] = $y;
        }

        return $yearList;
    }

    /**
     * 用于显示列表中的数据
     * @param $param
     * @return mixed
     */
    public function getAll($param)
    {
        [$where, $sort, $order, $offset, $limit] = $param;
        return $this->model->with($this->with)
            ->where($where)
            ->where($this->whereExtend)
            ->order($sort, $order)
            ->limit($offset, $limit)
            ->select();
    }

    /**
     * 用于展示列表的总条目数
     * @param $param
     * @return mixed
     */
    public function countAll($param)
    {
        [$where, $sort, $order, $offset, $limit] = $param;
        return $this->model->with($this->with)
            ->where($this->whereExtend)
            ->where($where)
            ->count();
    }


    /**
     * 常规的添加数据，如果无需重新backend中的add方法，可以直接使用backend中的add方法
     * 如果需要对add方法进行定制，可以在logic中重新该方法
     *
     * @param $params
     * @return \think\response\Json
     */
    public function add($params)
    {
        $result = false;
        Db::startTrans();
        try {
            if ($this->modelValidate) {
                $name = str_replace("\\model\\", "\\validate\\", get_class($this->model));
                $validate = is_bool($this->modelValidate) ? ($this->modelSceneValidate ? $name . '.add' : $name) : $this->modelValidate;
                $this->model->validateFailException(true)->validate($validate);
            }
            $result = $this->model->allowField(true)->save($params);
            Db::commit();
        } catch (ValidateException $e) {
            Db::rollback();
            $this->error($e->getMessage());
        } catch (PDOException $e) {
            Db::rollback();
            $this->error($e->getMessage());
        } catch (Exception $e) {
            Db::rollback();
            $this->error($e->getMessage());
        }
        if ($result !== false) {
            return self::success();
        } else {
            return self::error();
        }
    }

    /**
     * 获取一条记录
     * @param $where
     * @return mixed
     */
    public function get($where)
    {
        if(is_array($where)){
            return $this->model->where($where)->find();
        }
        return $this->model->find($where);
    }


    /**
     * 成功返回值
     * @param array $data
     * @param string $msg
     * @return \think\response\Json
     */
    protected function success($msg = '', $data = [])
    {
        return self::_tips(1, $data, $msg);
    }

    /**
     * 失败返回值
     * @param array $data
     * @param string $msg
     * @return \think\response\Json
     */
    protected function error($msg = '', $data = [])
    {
        return self::_tips(0, $data, $msg);
    }


    /**
     * 处理结果返回数据
     * @param $code
     * @param $data
     * @param $msg
     * @return \think\response\Json
     */
    private function _tips($code, $data, $msg)
    {
        return [
            'code' => $code,
            'msg' => $msg,
            'data' => $data
        ];
    }
}
